/**
 * Bestpay.com.cn Inc.
 * Copyright (c) 2011-2018 All Rights Reserved.
 */
package com.sgzn.sgpay.web.interceptor;

import com.alibaba.fastjson.JSON;
import com.sgzn.sgpay.enums.AppName;
import com.sgzn.sgpay.enums.SgsResponseCode;
import com.sgzn.sgpay.model.request.SgsSessionQueryRequest;
import com.sgzn.sgpay.model.response.SgsResultResponse;
import com.sgzn.sgpay.persistence.domain.TMchLoginSession;
import com.sgzn.sgpay.service.SgsSessionQueryService;
import com.sgzn.sgpay.util.SerialNoUtil;
import com.sgzn.sgpay.util.TranslateUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
import java.lang.reflect.Method;

/**
 * 小程序商户登录拦截器
 * @author zhongzhongyong
 * @version Id: MchLoginInterceptor.java, v 0.1 2018/6/21 21:53 zhongzhongyong Exp $$
 */
@Slf4j
@Component
public class MchLoginInterceptor implements HandlerInterceptor{

    @Autowired
    private SgsSessionQueryService sgsSessionQueryService;

    //进入handler之前执行
    @Override
    public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
        String url = httpServletRequest.getRequestURI();
        log.info("url=", url);

        //登录请求，放行
        if (url.endsWith("login") || url.endsWith("register") || url.endsWith("resetPwd")) {
            log.info("商户登录无需拦截");
            return true;
        }

        if (accessRequired((HandlerMethod) o)) {
            log.info("无需拦截");
            return true;
        }

        Object loginToken = httpServletRequest.getParameter("loginToken");
        if(loginToken == null){
            errorReturn(httpServletResponse);
        }else{
            TMchLoginSession session = getLoginSession(loginToken.toString());
            if(session != null){
                //token有效，查得有效session，将相关登录信息塞进请求中
                log.info("商户登录信息：{}",session);
                httpServletRequest.setAttribute("loginToken",session.getToken());
                httpServletRequest.setAttribute("mchId",session.getMchId());
                return true;
            }else{
                //token失效
                errorReturn(httpServletResponse);
            }
        }
        return false;//true表示放行
    }

    @Override
    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
        //do nothing here
    }

    @Override
    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
        //do nothing here
    }

    /**
     * 访问控制
     * @param handlerMethod
     * @return
     */
    private boolean accessRequired(HandlerMethod handlerMethod) {
        Method method = handlerMethod.getMethod();
        AccessRequired annotation = method.getAnnotation(AccessRequired.class);
        if (annotation != null && !annotation.required()) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * token失效返回
     * @param httpServletResponse
     */
    private void errorReturn(HttpServletResponse httpServletResponse) throws Exception{
        PrintWriter out = httpServletResponse.getWriter();
        String errMsg = getErrMsg();
        log.error(errMsg);
        out.print(errMsg);
    }

    /**
     * token失效时获取错误响应JSON字符串
     * @return
     */
    private String getErrMsg(){
        SgsResultResponse<String> response = new SgsResultResponse<String>();
        response.setErrorCode(SgsResponseCode.C_TOKEN_NOT_FOUND.getResponseCode());
        response.setErrorMsg(SgsResponseCode.C_TOKEN_NOT_FOUND.getResponseDesc());
        response.setResult(null);
        return JSON.toJSONString(response);
    }

    /**
     * 获取商户会话
     * @param loginToken
     * @return
     */
    private TMchLoginSession getLoginSession(String loginToken){
        SgsSessionQueryRequest request = new SgsSessionQueryRequest();
        request.setLoginToken(loginToken);
        request.setInitiationID(SerialNoUtil.generateSerialNo(AppName.SGW));
        SgsResultResponse<TMchLoginSession> sgsResp = sgsSessionQueryService.queryMchSession(request);
        if(TranslateUtil.isSuccessAbs(sgsResp.getErrorCode()) && sgsResp.getResult() != null){
            return sgsResp.getResult();
        }else{
            return null;
        }
    }


}